<template>
  <div style="position: relative">
    <div
      class="box"
      ref="boxRef"
      :style="{
        left: position.x + 'px',
        top: position.y + 'px',
        'flex-direction': positionLeft ? '' : 'row-reverse',
      }"
    >
      <div
        class="set-box"
        @mousedown="startDrag"
        @touchstart="startDrag"
        @click.stop="toogle"
      >
        <van-icon name="setting-o" size="23" />
      </div>

      <!-- flex 菜单根据位置决定展开方向 -->
      <div class="cont-box" ref="contBoxRef" v-if="show">
        <div class="rounded-full bg-#34d19d flex justify-center items-center">
          <div class="btn1 px-3 pt-4 pb-2" @click.stop="fullScreen">
            <van-icon name="enlarge" size="23" color="#fff" class="" />
          </div>
        </div>
        <div class="rounded-full bg-red flex justify-center items-center">
          <div class="btn2 p-3" @click.stop="goBack">
            <van-icon name="share" size="23" color="#fff" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
const show = ref(false); // 控制菜单展示
const setWidth = 800; //最大容器宽度
const position = ref({ x: 10, y: 10 }); // 初始化悬浮菜单位置
const isDragging = ref(false); // 是否在拖拽中
const offset = ref({ x: 0, y: 0 }); // 记录当前位置
const boxRef = ref(null); // 悬浮菜单容器
const contBoxRef = ref(null); // 悬浮菜单容器
const MARGIN = 10; // 吸附时与边界的距离
const positionLeft = ref(null); // 菜单位置是否靠左
const winW = ref((window.innerWidth - setWidth) / 2); //设备超出设定尺寸的一半距离
const providedGameWeb = inject("provided-gameWeb");
const getInitRight = () => {
  const el = boxRef.value;
  if (!el) return;
  const rect = el.getBoundingClientRect();

  const winWidth = window.innerWidth;
  // 初始靠右
  let initX =
    winWidth > setWidth
      ? setWidth - rect.width - MARGIN
      : winWidth - rect.width - MARGIN;
  position.value = { x: initX, y: 10 };
  positionLeft.value = false;
  console.log("getInitRight", position.value.x);
};
// 点击菜单
const toogle = (e) => {
  show.value = !show.value;
  // 如果在右边，当dom渲染完成之后重新计算位置
  nextTick(() => {
    if (!positionLeft.value && boxRef.value) {
      const el = boxRef.value;
      const rect = el.getBoundingClientRect();
      const winWidth = window.innerWidth;
      const limitWidth = winWidth > setWidth ? setWidth : winWidth;
      position.value.x = limitWidth - rect.width - MARGIN;
      console.log("toogle", position.value.x);
    }
  });
};
// 处理多点触控的情况
const getEventClientPosition = (e) => {
  if (e.touches && e.touches.length > 0) {
    return { clientX: e.touches[0].clientX, clientY: e.touches[0].clientY };
  }
  return { clientX: e.clientX, clientY: e.clientY };
};
// 开始拖动
const startDrag = (e) => {
  isDragging.value = true;
  const el = boxRef.value;
  if (!el) return;
  const rect = el.getBoundingClientRect();
  const { clientX, clientY } = getEventClientPosition(e);
  const winWidth = window.innerWidth;

  offset.value = {
    x: clientX - rect.left,
    y: clientY - rect.top,
  };

  // 特殊宽度条件下的偏移调整
  if (winWidth > setWidth) {
    offset.value.x += winW.value;
  }

  document.body.style.overflow = "hidden"; // 禁止滚动
};
// 拖动中
const onMove = (e) => {
  if (!isDragging.value) return;

  const { clientX, clientY } = getEventClientPosition(e);
  const el = boxRef.value;
  if (!el) return;

  const rect = el.getBoundingClientRect();
  const winWidth = window.innerWidth;
  const winHeight = window.innerHeight;

  // 计算新位置
  let newX = clientX - offset.value.x;
  let newY = clientY - offset.value.y;

  // 限制 X 轴边界（不能小于0，也不能超过容器宽度 - 悬浮框宽度）
  const limitWidth = Math.min(winWidth, setWidth);
  newX = Math.max(0, Math.min(newX, limitWidth - rect.width));

  // 限制 Y 轴边界
  newY = Math.max(0, Math.min(newY, winHeight - rect.height));

  position.value = { x: newX, y: newY };

  const halfWidth = Math.min(winWidth, setWidth) / 2;
  positionLeft.value = newX < halfWidth;
};
// 停止拖动
const endDrag = (e) => {
  isDragging.value = false;
  document.body.style.overflow = ""; // 恢复滚动
  const el = boxRef.value;
  if (!el) return;
  const rect = el.getBoundingClientRect();
  const winWidth = window.innerWidth;
  const winHeight = window.innerHeight;
  let { x: newX, y: newY } = position.value;
  const halfWidth = Math.min(winWidth, setWidth) / 2;

  // X 轴吸附逻辑
  if (newX < halfWidth) {
    newX = MARGIN; // 左侧吸附
  } else {
    newX = Math.min(setWidth, winWidth) - rect.width - MARGIN; // 右侧吸附
  }

  // Y 轴吸附逻辑
  if (newY < MARGIN) {
    newY = MARGIN; // 顶部吸附
  } else if (newY > winHeight - rect.height - MARGIN) {
    newY = winHeight - rect.height - MARGIN; // 底部吸附
  }

  // 更新位置
  position.value = { x: newX, y: newY };
};
// 全屏或取消全屏
const fullScreen = () => {
  const el = document.documentElement;
  if (!document.fullscreenElement) {
    // 当前不是全屏状态，进入全屏
    if (el.requestFullscreen) {
      el.requestFullscreen();
    } else if (el.webkitRequestFullscreen) {
      el.webkitRequestFullscreen(); // Safari
    } else if (el.mozRequestFullScreen) {
      el.mozRequestFullScreen(); // Firefox
    } else if (el.msRequestFullscreen) {
      el.msRequestFullscreen(); // IE/Edge
    } else {
      alert("你的浏览器不支持全屏模式");
    }
  } else {
    // 当前是全屏状态，退出全屏
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen(); // Safari
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen(); // Firefox
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen(); // IE/Edge
    }
  }
  // 靠右的时候要加上盒子尺寸
  if (!positionLeft.value && contBoxRef.value) {
    position.value.x =
      position.value.x + contBoxRef.value.getBoundingClientRect().width;
  }

  show.value = false;
};
// 返回给爷组件
const goBack = () => {
  providedGameWeb.value = false;
  if (document.fullscreenElement) {
    // 当前是全屏状态，退出全屏
    if (document.exitFullscreen) {
      document.exitFullscreen();
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen(); // Safari
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen(); // Firefox
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen(); // IE/Edge
    }
  }
};

// 绑定全局事件监听
onMounted(() => {
  document.addEventListener("mousemove", onMove, { passive: false });
  document.addEventListener("mouseup", endDrag);
  document.addEventListener("touchmove", onMove, { passive: false });
  document.addEventListener("touchend", endDrag);
  getInitRight();
});

// 清理副作用
onBeforeUnmount(() => {
  document.removeEventListener("mousemove", onMove);
  document.removeEventListener("mouseup", endDrag);
  document.removeEventListener("touchmove", onMove);
  document.removeEventListener("touchend", endDrag);
});
</script>

<style lang="scss" scoped>
.box {
  touch-action: none;
  user-select: none;
  -webkit-user-drag: none;
  position: absolute;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: transparent;
  height: 25px;
  border-radius: 40px;

  .set-box {
    width: 25px;
    height: 25px;
    border-radius: 50%;
    background: rgba(25, 137, 250, 0.5);
    color: #ffffff;
    text-align: center;
    line-height: 25px;
    z-index: 10;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .cont-box {
    width: 55px;
    border-radius: 40px;
    padding: 0 5px;
    z-index: 5;
    display: flex;
    justify-content: space-between;
    white-space: nowrap;
    background: transparent;
  }
  .btn1,
  .btn2 {
    color: #000;
  }

  .btn1 {
    // margin-right: 10px;
  }
}
</style>